<?php
/**
 * Created by PhpStorm.
 * User: xloong
 * Date: 2017/7/26
 * Time: 9:59
 */

namespace App\Http\Controllers\Api\V1;

use App\Models\Identify;
use App\Models\IdentifyImage;
use App\Models\RedPackets;
use App\Models\UserRedPacket;
use Illuminate\Http\Request;
use App\Models\YzToken;
use App\Services\Youzan\YZGetTokenClient;
use App\Services\Youzan\YZTokenClient;
class RedPacketController extends BaseController
{
    private $result = array('code' => '10000', 'message' => '系统服务异常', 'data' => array());

    /**抢红包接口
     * @param Request $request
     * @return mixed
     */
    public function getRedPackets(Request $request){
        // 自定义验证规则
        $rules = [
            'identify_id' => 'required|numeric',
        ];
        // 自定义提示
        $messages = [
            'identify_id.required' => ['code' => 20701, 'message' => '识别id不能为空.', 'data' => []],
            'identify_id.numeric'  => ['code' => 20702, 'message' => '识别id必须是一个数字.', 'data' => []],
        ];
        $validator = \Validator::make($request->all(), $rules, $messages);
        if ($validator->fails()) {
            $messages = $validator->errors()->toArray();
            foreach ($messages as $value) {
                $this->result['code'] = (int)$value[0]['code'];
                $this->result['message'] = $value[0]['message'];
                break;
            }
            return $this->response->array($this->result);
        }
        // 获取扫描识别信息的主键id
        $identifyId = $request->get('identify_id');
        //获取当前登陆用户信息
        $userInfo         = $this->user();
        try{
            //获取登陆用户今天已领红包信息
            $userRedPackets = UserRedPacket::where('user_id',$userInfo->id)
                ->where('created_at','>',date('Y-m-d'))->first();
            //根据规则每个用户每天只可领取一次红包
            if($userRedPackets){
                $this->result['code'] = 20703;
                $this->result['message'] = '您今天已领取过红包,请明天再来';
                return $this->response->array($this->result);
            }
            //根据识别id获取红包识别信息
            $identifySql   = Identify::find($identifyId);
            //判断是否存在红包信息
            if(empty($identifySql) || empty($redPackets=json_decode($identifySql->red_packets,true))){
                $this->result['code'] = 20704;
                $this->result['message'] = '参数错误，请稍后重新尝试';
                return $this->response->array($this->result);
            }
            //这种做法是为了兼容老版本红包信息
            if(!isset(current($redPackets)['probability'])){
                $redPackets = RedPackets::whereIn('id',$redPackets)
                              ->select('id as red_packet_id','probability')->get()->toArray();
            }
            //根据输入概率获得中奖的优惠卷id
            $redPacketsId     = $this->randCouponId($redPackets);
            if(0 == $redPacketsId){
                $this->result['code'] = 20711;
                $this->result['message'] = '很抱歉，您没有中奖';
                return $this->response->array($this->result);
            }
            //获取红包信息
            $redPacketsObject = RedPackets::find($redPacketsId);
            //构造发放红包参数
            $takeCouponParam = ['mobile'=>$userInfo->yz_mobile,
                'coupon_group_id'=>$redPacketsObject->yz_red_packets_id];
            //调用有赞发红包接口
            $takeCoupon   = $this->youZanInterface(config('tools.youZan.coupon.take'),$takeCouponParam);
            //接口返回错误信息，直接将错误信息返回前台
           if(isset($takeCoupon['error_response'])){
               $this->result['code'] = 20704;
               $this->result['message'] = $takeCoupon['error_response']['msg'];
               return $this->response->array($this->result);
           }
            //记录当前用户已领优惠卷信息
            $this->userRedPacketsAdd($userInfo->id,$takeCoupon,$identifyId);
            //更新优惠卷剩余数量
            $this->updateSurplusNum($redPacketsObject->id,$redPacketsObject->surplus_num);
            $this->result['code']    = 200;
            $this->result['message'] = 'ok';
            $this->result['data']    = $takeCoupon['response']['promocard'];
            return $this->response->array($this->result);
        }catch (\Exception $e){
            return $this->response->array($this->result);
        }
    }

    /**
     * 根据概率计算当前用户获得的红包id
     * @param array $prizes
     * @return bool
     */
    protected function randCouponId($prizes){
        $randNum      = mt_rand(1,100);
        $probability  = 0;
        $redPacketsId = 0;
        foreach ($prizes as $key=>$prize){
            if($randNum <= $prize['probability'] + $probability && $randNum > $probability){
                $redPacketsId = $prize['red_packet_id'];
                break;
            }else{
               $probability +=$prize['probability'] ;
            }
        }
        return $redPacketsId;
    }

    /**
     * 获取有赞认证token
     * @return YzToken|mixed
     */
    public function getYouZanToken(){
        $sqlYzToken = YzToken::where('user_id',0)->orderBy('created_at','DESC')->first();
        //请求到得token未过期，直接使用
        if(!empty($sqlYzToken) &&time() - strtotime($sqlYzToken->updated_at) < $sqlYzToken->expired_at){
            return $sqlYzToken->toArray();
        }

        $client_id = config('tools.youZan.client_id');//请填入有赞云控制台的应用client_id
        $client_secret = config('tools.youZan.client_secret');//请填入有赞云控制台的应用client_secret
        $type   = config('tools.youZan.client_type');//请填入开发者后台所填写的回调地址，本示例中回调地址应指向本文件。
        $keys['kdt_id'] = config('tools.youZan.client_kdt_id');//自用型店铺id

        $token = new YZGetTokenClient( $client_id , $client_secret );
        $loginInfo = $token->get_token( $type , $keys );
        if(isset($loginInfo['error'])){
            return redirect()->back()->with('fail', '登陆有赞失败，请稍后重试！');
        }

        //不存在记录信息直接新建
        if(empty($sqlYzToken)){
            $yzClass  = new YzToken();
            $yzClass->access_token = $loginInfo['access_token'];
            $yzClass->expired_at   = $loginInfo['expires_in'];
            $yzClass->scope        = $loginInfo['scope'];
            $yzClass->save();
            return $yzClass;
        }

        //更新数据库中存储得token信息
        $sqlYzToken->access_token = $loginInfo['access_token'];
        $sqlYzToken->expired_at   = $loginInfo['expires_in'];
        $sqlYzToken->scope        = $loginInfo['scope'];
        $sqlYzToken->save();
        return $loginInfo;
    }

    /** 调用有赞接口入口
     * @param $method
     * @param $params
     * @param $token bool|string
     * @return mixed
     */
    public function youZanInterface($method,$params,$token=false){
        if(false === $token){
            $youZanToken         = $this->getYouZanToken()['access_token'];
        }else{
            $youZanToken         = $token;
        }
        $client        = new YZTokenClient($youZanToken);
        $api_version   = '3.0.0';
        $operateStatus = $client->post($method,$api_version,$params);
        return $operateStatus;
    }

    /**更新数据库中剩余红包数量
     * @param $red_packets_id
     * @param $red_num
     */
    public function updateSurplusNum($red_packets_id,$red_num){
            RedPackets::where('id',$red_packets_id)->update(['surplus_num'=> $red_num-1]);
    }

    /**
     * 添加用户抢红包记录信息
     * @param $user_id
     * @param $red_packets
     */
    public function userRedPacketsAdd($user_id,$red_packets,$identify_id){
        $userRedClass = new UserRedPacket();
        $userRedClass -> user_id          = $user_id;
        $userRedClass -> red_packets_info = json_encode($red_packets);
        $userRedClass -> identify_id      = $identify_id;
        $userRedClass ->save();
    }

    /**
     * @desc  判断当前用户是否可以抢红包
     * @return mixed
     */
    public function hasYouZanInfo(){
        //获取用户信息
       $user = $this->user();
       if(empty($user->yz_mobile)){
           //判断是否绑定有赞账号
           $this->result['code'] = 21500;
           $this->result['message'] = '请绑定有赞账号';
           return $this->response->array($this->result);
       //判断用户是否已经抢过当前商品对应的红包
       }elseif (UserRedPacket::where('user_id',$user->id)->where('created_at','>',date('Y-m-d'))->first()){
           $this->result['code'] = 21600;
           $this->result['message'] = '您今日已抢过红包';
           return $this->response->array($this->result);
       //一切正常,进入抢红包页面
       } else{
           $this->result['code'] = 200;
           $this->result['message'] = 'ok';
           return $this->response->array($this->result);
       }
    }

}